home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Modules / BackSpaceModules / Source / CreepyFace / CFWireFrame.m < prev    next >
Text File  |  1994-03-23  |  11KB  |  482 lines

  1. #import "CFWireFrame.h"
  2.  
  3. @implementation CFWireFrame:Object
  4.  
  5.  
  6. // this code is copyright Darcy Brockbank, 1993
  7. //
  8. // You may freely reuse and distribute this code in any way shape or
  9. // form, provided that this notice stays intact.
  10. //
  11. // darcy@hasc.ca, samurai@cs.mcgill.ca
  12. //
  13. // StefView was implemented out of WorldSpaceView and retains some of the
  14. // movement properties...
  15. //
  16. // The code for WorldSpaceView was written by Sam Streeper at CreepyFace, I think,
  17. // and there were two other contributors, but I can't find their names in the
  18. // source for it.
  19. //
  20. // CreepyFaceView shows a simple (ha!) spinning CreepyFace logo, in full 3D. The 3D code
  21. // came from an app I wrote a long time ago called "CFWireFrame", and so the code
  22. // is pretty scary. As well, this thing is only a quick hack, though a nice one.
  23. //
  24. // This thing has room for improvement, and if you do so, send me a copy!
  25. //
  26. // - darcy
  27.  
  28. #define SCALE 1.0045
  29.  
  30. - getCentre:(float*) x:(float *)y :(float *)z
  31. {
  32.     *x=myCentre.x;
  33.     *y=myCentre.y;
  34.     *z=myCentre.z;
  35.     return self;
  36. }
  37.  
  38. - getFrameColour:(float *)r :(float *)g :(float *)b
  39. {
  40.     *r=myFrameColour.red;
  41.     *b=myFrameColour.blue;
  42.     *g=myFrameColour.green;
  43.     return self;
  44. }
  45.  
  46. - getTagColour:(float *)r :(float *)g :(float *)b
  47. {
  48.     *r=myTagColour.red;
  49.     *b=myTagColour.blue;
  50.     *g=myTagColour.green;
  51.     return self;
  52. }
  53.  
  54.  
  55. static int count(const char *s,char thisChar)
  56. {
  57.     int c=0;
  58.     
  59.     for (;*s!=(char)0;s++)    if (*s==thisChar) c++;
  60.     return (c);
  61. }
  62.  
  63. #define LIM 6400000.0
  64.  
  65. - init
  66. {
  67.     [super init];
  68.     myLineWidth=0.1;
  69.     psint=sin(0.085);
  70.     nsint=-psint;
  71.     cost=cos(0.085);
  72.      bbox[0]=-LIM;
  73.     bbox[1]=-LIM;
  74.     bbox[2]=2*LIM;
  75.     bbox[3]=2*LIM;
  76.     myTable = [[NXStringTable alloc] init];
  77.     dimension=4;
  78.     return self;
  79. }
  80.  
  81. - free
  82. {
  83.     [myTable free];
  84.     return [super free];
  85. }
  86.  
  87. - addMyPS:(char)command
  88. {
  89.     myPSCommands[numberOfMyPS++]=command;
  90.     return self;
  91. }
  92.  
  93. - addPoint:(float)x :(float)y :(float)z
  94. {
  95.     myCoords[numberOfCoords*4]=x;
  96.     myCoords[numberOfCoords*4+1]=y;
  97.     myCoords[numberOfCoords*4+2]=z;
  98.     myCoords[numberOfCoords*4+3]=1.0;
  99.     numberOfCoords++;
  100.     return self;
  101. }
  102.     
  103. - moveTo:(float)x:(float)y:(float)z
  104. {
  105.     int i;
  106.     
  107.     for(i=0;i<numberOfCoords*dimension;i+=dimension){
  108.         myCoords[i]+=(x-myCentre.x);
  109.         myCoords[i+1]+=(y-myCentre.y);
  110.         myCoords[i+2]+=(z-myCentre.z);
  111.     }
  112.     for(i=0;i<numberOfTags*coordsInATag*dimension;i+=dimension){
  113.         myTags[i]+=(x-myCentre.x);
  114.         myTags[i+1]+=(y-myCentre.y);
  115.         myTags[i+2]+=(z-myCentre.z);
  116.     }
  117.     myCentre.x=x;
  118.     myCentre.y=y;
  119.     myCentre.z=z;
  120.     return self;
  121. }
  122.  
  123.  
  124. - drawYourself:(float)zoom centeredOn:(float)X :(float)Y;
  125. {
  126.     int i,j,x;
  127.     int stop,start;
  128.     BOOL behindMe;
  129.     DPSUserPathAction op;
  130.  
  131.     behindMe=NO;
  132.     stop=numberOfCoords*dimension;
  133.     for (i=0,j=0;i<stop;j+=2,i+=dimension){
  134.         if (myCoords[i+2]>=-0.001) {
  135.             behindMe=YES;
  136.             break;
  137.         }
  138.         output[j]=((myCoords[i])*(-zoom/myCoords[i+2]))+X;
  139.         output[j+1]=((myCoords[i+1])*(-zoom/myCoords[i+2]))+Y;
  140.     }
  141.     if (!behindMe && stop!=0 && numberOfCoords>0){
  142.             PSsetrgbcolor(myFrameColour.red,myFrameColour.green,myFrameColour.blue);
  143.             DPSDoUserPath(output,2*numberOfCoords,dps_float,myPSCommands,
  144.             numberOfMyPS,bbox,dps_ustroke);
  145.     }
  146.     if (numberOfTags){
  147.         op=dps_ufill;
  148.         for(x=0;x<numberOfTags;x++){
  149.             behindMe=NO;
  150.             start=x*coordsInATag*dimension;
  151.             if (!(myTags[2+start]>=myCentre.z)) { // closer than centre
  152.                 op = dps_ustroke;
  153.             }
  154.             stop=start+(coordsInATag*dimension);
  155.             for(j=0,i=start;i<stop;j+=2,i+=dimension){
  156.                 if (myTags[i+2]>=0){
  157.                      behindMe=YES;
  158.                      break;
  159.                 }
  160.                 output[j]=((myTags[i])*(-zoom/myTags[i+2]))+X;
  161.                 output[j+1]=((myTags[i+1])*(-zoom/myTags[i+2]))+Y;
  162.             }
  163.             if (!behindMe && coordsInATag > 0){
  164.                 PSsetrgbcolor(myTagColour.red,myTagColour.green,myTagColour.blue) ;
  165.                 DPSDoUserPath(output,(2*coordsInATag),dps_float,myTagPSCommands,
  166.                     numberOfTagPS,bbox,op);
  167.             }
  168.         }
  169.     }
  170.     return self;
  171. }        
  172.  
  173. - rotate: (Direction) direction aroundAxis:(Axis) thisAxis atOrigin:(Origin) thisOrigin    
  174. {
  175.     double mysint;
  176.     double s1,s2,s3;
  177.     Origin origin;
  178.     int i;
  179.  
  180.     if (direction==negative) {
  181.         mysint=nsint;
  182.     }
  183.     else {
  184.         mysint=psint;
  185.     }
  186.  
  187.     origin=thisOrigin;
  188.     switch(thisAxis){
  189.     case x:
  190.         for (i=0;i<numberOfCoords*dimension;i+=dimension){
  191.             s2=myCoords[i+1]-origin.y;
  192.             s3=myCoords[i+2]-origin.z;
  193.             myCoords[i+1]=(float)((s2)*cost-(s3)*mysint)+origin.y;
  194.             myCoords[i+2]=(float)((s2)*mysint+(s3)*cost)+origin.z;
  195.         }
  196.         for (i=0; i<(numberOfTags*coordsInATag)*dimension; i+=dimension){
  197.             s2=myTags[i+1]-origin.y;
  198.             s3=myTags[i+2]-origin.z;
  199.             myTags[i+1]=(float)((s2)*cost-(s3)*mysint)+origin.y;
  200.             myTags[i+2]=(float)((s2)*mysint+(s3)*cost)+origin.z;
  201.         }
  202.         s2=myCentre.y-origin.y;
  203.         s3=myCentre.z-origin.z;
  204.         myCentre.y=(float)(s2*cost-s3*mysint)+origin.y;
  205.         myCentre.z=(float)(s2*mysint+s3*cost)+origin.z;
  206.         break;
  207.     case y:
  208.         for (i=0; i<numberOfCoords*dimension; i+=dimension){
  209.             s1=myCoords[i]-origin.x;
  210.             s3=myCoords[i+2]-origin.z;
  211.             myCoords[i]=(float)((s1)*cost+s3*mysint)+origin.x;
  212.             myCoords[i+2]=(float)((-s1)*mysint+s3*cost)+origin.z;
  213.         }    
  214.         for (i=0; i<(numberOfTags*coordsInATag*dimension); i+=dimension){
  215.             s1=myTags[i]-origin.x;
  216.             s3=myTags[i+2]-origin.z;
  217.             myTags[i]=(float)((s1)*cost+s3*mysint)+origin.x;
  218.             myTags[i+2]=(float)((-s1)*mysint+s3*cost)+origin.z;
  219.         }    
  220.         s1=myCentre.x-origin.x;
  221.         s3=myCentre.z-origin.z;
  222.         myCentre.x=(float)(s1*cost+s3*mysint)+origin.x;
  223.         myCentre.z=(float)(-s1*mysint+s3*cost)+origin.z;
  224.         break;
  225.     case z:
  226.         for (i=0; i<numberOfCoords*dimension; i+=dimension){
  227.             s1=myCoords[i]-origin.x;
  228.             s2=myCoords[i+1]-origin.y;
  229.             myCoords[i]=(float)(s1*cost-s2*mysint)+origin.x;
  230.             myCoords[i+1]=(float)(s1*mysint+s2*cost)+origin.y;
  231.         }
  232.         for (i=0; i<(numberOfTags*coordsInATag*dimension); i+=dimension){
  233.             s1=myTags[i]-origin.x;
  234.             s2=myTags[i+1]-origin.y;
  235.             myTags[i]=(float)(s1*cost-s2*mysint)+origin.x;
  236.             myTags[i+1]=(float)(s1*mysint+s2*cost)+origin.y;
  237.         }
  238.         s2=myCentre.y-origin.x;
  239.         s1=myCentre.x-origin.y;
  240.         myCentre.x=(float)(s1*cost-s2*mysint)+origin.x;
  241.         myCentre.y=(float)(s1*mysint+s2*cost)+origin.y;
  242.     }
  243.     return self;
  244. }
  245.     
  246. - translate: (Direction) direction alongAxis: (Axis) thisAxis atRate:(float) rate
  247. {
  248.     float mydir;
  249.     int i;
  250.     
  251.     if(direction==negative) {
  252.         mydir=-1*rate;
  253.     }
  254.     else {
  255.         mydir=rate;
  256.     }
  257.     
  258.     switch(thisAxis) {
  259.     case x:
  260.         myCentre.x+=mydir;
  261.         break;
  262.     case y:
  263.         myCentre.y+=mydir;
  264.         break;
  265.     case z:
  266.         myCentre.z+=mydir;
  267.         break;
  268.     }        
  269.     for(i=0;i<numberOfCoords*dimension;i+=dimension){
  270.         myCoords[i+thisAxis]+=mydir;
  271.     }
  272.     for(i=0;i<numberOfTags*coordsInATag*dimension;i+=dimension){
  273.         myTags[i+thisAxis]+=mydir;
  274.     }
  275.     return self;
  276. }            
  277.     
  278.  
  279.  
  280. - setCentre:(float) x :(float)y :(float)z
  281. {
  282.     printf("Setting\n");
  283.     myCentre.x=x;
  284.     myCentre.y=y;
  285.     myCentre.z=z;
  286.     return self;
  287. }
  288.  
  289. - setFrameColour:(float) r :(float)g :(float)b
  290. {
  291.     myFrameColour.red=r;
  292.     myFrameColour.green=g;
  293.     myFrameColour.blue=b;
  294.     return self;
  295. }
  296.  
  297. - setTagColour:(float) r :(float)g :(float)b
  298. {
  299.     myTagColour.red=r;
  300.     myTagColour.green=g;
  301.     myTagColour.blue=b;
  302.     return self;
  303. }    
  304.  
  305. - setNumberOfTags:(int)count
  306. {
  307.     numberOfTags=count;
  308.     return self;
  309. }
  310.  
  311. - setCoordsInATag:(int)count;
  312. {
  313.     coordsInATag=count;
  314.     return self;
  315. }
  316.  
  317. - setNumberOfTagPS:(int)count;
  318. {
  319.     numberOfTagPS=count;
  320.     return self;
  321. }
  322.  
  323. - setNumberOfCoords:(int) count;
  324. {
  325.     numberOfCoords=count;
  326.     return self;
  327. }
  328.  
  329. - setNumberOfMyPS:(int) count;
  330. {
  331.     numberOfMyPS=count;
  332.     return self;
  333. }
  334.  
  335. - setBoundingBox:(float *) thisBox
  336. {
  337.     bbox[0]=-1.0e16;
  338.     bbox[1]=-1.0e16;
  339.     bbox[2]=1.0e16;
  340.     bbox[3]=1.0e16;
  341.     
  342.     return self;
  343. }
  344.  
  345. - (int) getNumberOfMyPS
  346. {
  347.     return  numberOfMyPS;
  348. }
  349.  
  350. - (int) getNumberOfPoints
  351. {
  352.     return (numberOfCoords);
  353. }
  354.  
  355. - makeCFWireFrame:(const char *)thisFrame
  356. {
  357.     const char *frameCoords,*framePS,*tagCoords,*numOfTags,*frameColour,
  358.         *frameCentre,*tagColour,*tagPS, *coordsInTag,*check;
  359.     int i;
  360.     char ps=0;
  361.     
  362.     
  363.     if ([myTable readFromFile:thisFrame]==nil){
  364.         return self;
  365.         NXRunAlertPanel(thisFrame,"The file is not in the given directory. Please fix this problem and restart the application.","Quit",NULL,NULL);
  366.         [NXApp terminate:self];
  367.     }
  368.  
  369.  
  370.     
  371.     frameCoords=[myTable valueForStringKey:"FramePoints"];
  372.     tagCoords=[myTable valueForStringKey:"TagPoints"];
  373.     frameColour=[myTable valueForStringKey:"FrameColor"];
  374.     tagColour=[myTable valueForStringKey:"TagColor"];
  375.     framePS=[myTable valueForStringKey:"FramePS"];
  376.     coordsInTag=[myTable valueForStringKey:"PointsPerTag"];
  377.     numOfTags=[myTable valueForStringKey:"NumberOfTags"];
  378.     frameCentre=[myTable valueForStringKey:"FrameCenter"];
  379.     tagPS=[myTable valueForStringKey:"TagPS"];
  380.     
  381.     numberOfTags=atoi(numOfTags);
  382.     coordsInATag=atoi(coordsInTag);
  383.     numberOfCoords=count(frameCoords,',')+1;
  384.  
  385.     numberOfMyPS=count(framePS,',')+1;
  386.     numberOfTagPS=count(tagPS,',')+1;
  387.     
  388.     sscanf(frameColour,"%f , %f , %f",
  389.         &myFrameColour.red,&myFrameColour.green,&myFrameColour.blue);
  390.     sscanf(tagColour,"%f , %f , %f",
  391.         &myTagColour.red,&myTagColour.green,&myTagColour.blue);
  392.     
  393.     sscanf(frameCentre,"%f , %f , %f",&myCentre.x,&myCentre.y,&myCentre.z);
  394.     
  395.     for(i=0,check=framePS;check!=(char *)1;i++,check=index(check,',')+1){
  396.         switch(check[0]){
  397.         case 'a':    
  398.             switch (check[3]){
  399.             case 'n':    ps=dps_arcn; break;
  400.             case 't':    ps=dps_arct; break;
  401.             default:    ps=dps_arc;
  402.             }
  403.             break;
  404.         case 'm':    ps=dps_moveto;break;
  405.         case 'r':    
  406.             switch(check[1]){ 
  407.             case 'm':    ps=dps_rmoveto;break;
  408.             case 'l':    ps=dps_rlineto;    break;
  409.             default:    ps=dps_rcurveto;
  410.             }
  411.             break;
  412.             switch(check[1]){
  413.             case 'l' :ps=dps_closepath;    break;
  414.             case 'u':ps=dps_curveto;    break;
  415.             }
  416.         case 'c':    
  417.             switch(check[1]){
  418.             case 'l' :ps=dps_closepath;    break;
  419.             case 'u':ps=dps_curveto;    break;
  420.             }
  421.             break;
  422.         case 'u':    ps=dps_ucache; break;
  423.         case 'l' :     ps=dps_lineto;    break;
  424.         default:    ps=-1;
  425.         }
  426.         myPSCommands[i]=ps;
  427.     }    
  428.  
  429.     for(i=0,check=tagPS;check!=(char *)1;i++,check=index(check,',')+1){
  430.         switch(check[0]){
  431.         case 'a':
  432.             switch (check[3]){
  433.             case 'n':    ps=dps_arcn;    break;
  434.             case 't':    ps=dps_arct;    break;
  435.             default:    ps=dps_arc;
  436.             }
  437.             break;
  438.         case 'm':    ps=dps_moveto;    break;
  439.         case 'r':
  440.             switch(check[1]){
  441.             case 'm':    ps=dps_rmoveto; break;
  442.             case 'l':    ps=dps_rlineto;     break;
  443.             default:    ps=dps_rcurveto;
  444.             }
  445.             break;
  446.         case 'c':    
  447.             switch(check[1]){
  448.             case 'l' :ps=dps_closepath;    break;
  449.             case 'u':ps=dps_curveto;    break;
  450.             }
  451.             break;
  452.         case 'u':    ps=dps_ucache;    break;
  453.         case 'l' :     ps=dps_lineto;    break;
  454.         default:    ps=-1;    break;
  455.         }
  456.         myTagPSCommands[i]=ps;
  457.     }    
  458.     
  459.     for (i=0,check=frameCoords;i<numberOfCoords;i++,check=(index(check,',')+1)){
  460.         sscanf(check," %f",(&myCoords[i]));
  461.     }
  462.     for (i=0,check=tagCoords;i<numberOfTags*coordsInATag*4;i++,check=(index(check,',')+1)){
  463.         sscanf(check," %f",(&myTags[i]));
  464.     }
  465.     numberOfCoords/=4;
  466.  
  467.     return self;
  468. }
  469.  
  470. - readBinaryCodeFrom: (char *) thisFile
  471. {
  472.     return self;
  473. }
  474.  
  475.     
  476.     
  477.     
  478.     
  479.     
  480.  
  481. @end
  482.